package com.sx.pic.demos.web;

import cn.hutool.core.date.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.resource.HttpResource;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;

@Controller
public class BasicController {
    static final Logger LOGGER = LoggerFactory.getLogger(BasicController.class);

    @RequestMapping("/")
    public String html() {
        return "index.html";
    }

    @RequestMapping(value = "/editPic", method = RequestMethod.POST)
    @ResponseBody
    public void editPic(@RequestBody MultipartFile[] file) throws IOException {
        File fileDir = new File("");
        String filePath = fileDir.getAbsolutePath() + File.separator + "pic" + File.separator;
        File file1 = new File(filePath);
        if (!file1.exists()) {
            file1.mkdirs();
        }
        System.out.println(fileDir.getAbsolutePath());
        for (MultipartFile multipartFile : file) {
            String saveDirPath = filePath + multipartFile.getOriginalFilename();
            BufferedImage image = ImageIO.read(multipartFile.getInputStream());
            LOGGER.info("=========路径:{}", saveDirPath);
            LOGGER.info("=========大小:{}", multipartFile.getSize() / 1024 + "KB");
            LOGGER.info("=========高:{}", image.getHeight() + "px");
            LOGGER.info("=========宽:{}", image.getWidth() + "px");
            try (InputStream inputStream = multipartFile.getInputStream();
                 BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
                 BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(saveDirPath))) {
                byte[] bytes = new byte[1024];
                int len = 0;
                while ((len = bufferedInputStream.read(bytes)) != -1) {
                    bufferedOutputStream.write(bytes, 0, len);
                }
            }
        }
    }

    @RequestMapping(value = "/getSize", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> getSize(@RequestBody Map<String, Object> map) throws IOException {
        HashMap<String, Object> objectObjectHashMap = new HashMap<>();
        String base64Str = map.get("base64Str").toString();
        int i = base64Str.indexOf(",");
        String substring = base64Str.substring(i + 1);
        //base64转字节
        byte[] bytes = Base64.getDecoder().decode(substring);
        String s = formatFileSize(bytes.length);
        LOGGER.info("=========大小:{}", s);
        InputStream inputStream = new ByteArrayInputStream(bytes);
        // 读取原始图片
        BufferedImage originalImage = ImageIO.read(inputStream);

        // 压缩图片质量
        byte[] compressedImage = compressImageQuality(originalImage, Float.parseFloat(map.get("quality").toString()));
        long length = compressedImage.length;
        String s1 = formatFileSize(length);
        LOGGER.info("=========大小:{}", s1);
        objectObjectHashMap.put("size", s1);
        //字节转base64
        String base64 = Base64.getEncoder().encodeToString(compressedImage);
        objectObjectHashMap.put("base64Str", base64);
        return objectObjectHashMap;
    }

    @RequestMapping(value = "/down", method = RequestMethod.POST)
    public void down(@RequestBody Map<String, Object> map, HttpServletResponse response) throws IOException {
        String base64Str = map.get("base64Str").toString();
        int i = base64Str.indexOf(",");
        String substring = base64Str.substring(i + 1);
        //base64转字节
        byte[] bytes = Base64.getDecoder().decode(substring);
        InputStream inputStream = new ByteArrayInputStream(bytes);
        // 读取原始图片
        BufferedImage originalImage = ImageIO.read(inputStream);
        // 压缩图片质量
        byte[] compressedImage = compressImageQuality(originalImage, Float.parseFloat(map.get("quality").toString()));
        //下载
        String filename = "image_" + DateUtil.now();
        filename = new String(filename.getBytes("UTF-8"), "ISO-8859-1");
        response.setContentType("application/force-download");
        response.setCharacterEncoding("utf-8");
        response.addHeader("Content-disposition", "attachment;fileName=" + filename + ".jpg");

        try (BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream())) {
            bos.write(compressedImage);
            bos.flush();
        } catch (
                Exception e) {
            LOGGER.error("下载图片失败", e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            response.getWriter().write("下载失败: " + e.getMessage());
        }
    }

    public byte[] compressImageQuality(BufferedImage originalImage, float quality) throws IOException {
        // 确保质量在有效范围内 (1-100)
        quality = Math.max(1f, Math.min(100f, quality));

        // 将质量转换为0-1范围，1为最高质量
        float jpegQuality = quality / 100f;

        // 检查图片是否有透明度，如果有则考虑转换为RGB
        BufferedImage processedImage = originalImage;
        if (originalImage.getColorModel().hasAlpha()) {
            // 创建不带透明度的版本
            processedImage = new BufferedImage(
                    originalImage.getWidth(),
                    originalImage.getHeight(),
                    BufferedImage.TYPE_INT_RGB
            );

            // 填充白色背景
            java.awt.Graphics2D g = processedImage.createGraphics();
            g.setColor(java.awt.Color.WHITE);
            g.fillRect(0, 0, originalImage.getWidth(), originalImage.getHeight());
            g.drawImage(originalImage, 0, 0, null);
            g.dispose();
        }

        // 获取JPEG格式的ImageWriter
        ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next();

        try {
            // 设置压缩参数
            ImageWriteParam param = writer.getDefaultWriteParam();

            // 检查是否支持压缩
            if (param.canWriteCompressed()) {
                param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                param.setCompressionQuality(jpegQuality);
            }

            // 输出流
            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            try (ImageOutputStream ios = ImageIO.createImageOutputStream(baos)) {
                writer.setOutput(ios);

                // 写入压缩后的图片
                writer.write(null, new IIOImage(processedImage, null, null), param);
            }

            return baos.toByteArray();
        } finally {
            // 清理资源
            writer.dispose();
        }
    }

    private String formatFileSize(long size) {
        java.text.DecimalFormat df = new java.text.DecimalFormat("#.##");

        if (size < 1024) {
            return size + " B";
        }
        return df.format((double) size / 1024) + " KB";
    }
}